package siii;

import java.awt.*;
import java.awt.event.*;

import javax.media.*;
import javax.media.protocol.*;

public class JMF extends Frame implements ActionListener, ItemListener, WindowListener,
  ControllerListener {

  CaptureDeviceInfo audioCDI = null;
  CaptureDeviceInfo videoCDI = null;
  String audioDeviceName = null;
  String videoDeviceName = null;
  Player videoPlayer;
  Player audioPlayer;
  Format videoFormat;
  Format audioFormat;
  Player dualPlayer;  //for merging audio and video data sources

  DataSource dataSource; //of the capture devices

  public JMF(String title) {
    super(title);
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent we) {
        dispose();
      }
    });
    MenuBar mb = new MenuBar();
    setMenuBar(mb);
    Menu menuConfigure = new Menu("Configure");
    mb.add(menuConfigure);

    Menu menuAction = new Menu("Action");
    mb.add(menuAction);

    /* menu items for Configure */
    MenuItem menuItemSetting = new MenuItem("Capture Device");
    menuItemSetting.addActionListener(this);
    menuConfigure.add(menuItemSetting);

    /* menu items for Action */

    MenuItem a1 = new MenuItem("Capture");
    a1.addActionListener(this);
    menuAction.add(a1);
    MenuItem a2 = new MenuItem("Play");
    a2.addActionListener(this);
    menuAction.add(a2);
    MenuItem a3 = new MenuItem("Stop");
    a3.addActionListener(this);
    menuAction.add(a3);

  }

  public void actionPerformed(ActionEvent ae) {
    String command = ae.getActionCommand().toString();
    if (command.equals("Capture Device")) {
      registerDevices();
    }
    else if (command.equals("Play")) {
      play();
    }
    else if (command.equals("Capture")) {
      capture();
    }
    else if (command.equals("Stop")) {
      stop();
    }
  }

  void registerDevices() {
    CaptureDeviceDialog cdDialog = new
      CaptureDeviceDialog(this, "Capture Device", true);
    cdDialog.show();
    if (!cdDialog.hasConfigurationChanged())
      return;

    //configuration has changed, update variables.
    audioCDI = cdDialog.getAudioDevice();
    if (audioCDI!=null) {
      audioDeviceName = audioCDI.getName();
      System.out.println("Audio Device Name: " + audioDeviceName);
    }

    videoCDI = cdDialog.getVideoDevice();
    if (videoCDI!=null) {
      videoDeviceName = videoCDI.getName();
      System.out.println("Video Device Name: " + videoDeviceName);
    }

    //Get formats selected, to be used for creating DataSource
    videoFormat = cdDialog.getVideoFormat();
    audioFormat = cdDialog.getAudioFormat();
  }

  void capture() {
    if (audioCDI==null && videoCDI==null)
      registerDevices();

    try {
      if (!(audioCDI==null && videoCDI==null)) {

     /* This works, but now we end up having 2 players

        videoPlayer = Manager.createPlayer(videoCDI.getLocator());
        audioPlayer = Manager.createPlayer(audioCDI.getLocator());
        videoPlayer.addControllerListener(this);
        videoPlayer.start();
        audioPlayer.start();
     */
        DataSource[] dataSources = new DataSource[2];
        System.out.println("Creating data sources.");

        dataSources[0] = Manager.createDataSource(audioCDI.getLocator());
        dataSources[1] = Manager.createDataSource(videoCDI.getLocator());
        DataSource ds = Manager.createMergingDataSource(dataSources);
        dualPlayer = Manager.createPlayer(ds);
        dualPlayer.addControllerListener(this);
        dualPlayer.start();
      }
      else
        System.out.println("CDI not found.");
    }
    catch (Exception e) {
      System.out.println(e.toString());
    }
  }

  void play() {
    try {
      FileDialog fd = new FileDialog(this, "Select File", FileDialog.LOAD);
      fd.show();
      String filename = fd.getDirectory() + fd.getFile();
      dualPlayer = Manager.createPlayer(new MediaLocator("file:///" + filename));

      System.out.println("Adding controller listener");
      dualPlayer.addControllerListener(this);

      System.out.println("Starting player ...");
      dualPlayer.start();
    }
    catch (Exception e) {
      System.out.println(e.toString());
    }
  }

  void stop() {
    if (dualPlayer!=null) {
      dualPlayer.stop();
      dualPlayer.deallocate();
    }
  }

public synchronized void controllerUpdate(ControllerEvent event) {
    System.out.println(event.toString());

    if (event instanceof RealizeCompleteEvent) {
      Component comp;

      System.out.println("Adding visual component");
      if ((comp = dualPlayer.getVisualComponent()) != null)
        add ("Center", comp);
      System.out.println("Adding control panel");
      if ((comp = dualPlayer.getControlPanelComponent()) != null)
        add("South", comp);
      validate();
    }
  }

  public void itemStateChanged(ItemEvent ie) {}
  public void windowActivated(WindowEvent we) {}
  public void windowClosed(WindowEvent we) {}
  public void windowClosing(WindowEvent we) {}
  public void windowDeactivated(WindowEvent we) {}
  public void windowDeiconified(WindowEvent we) {}
  public void windowIconified(WindowEvent we) {}
  public void windowOpened(WindowEvent we) {}



 public static void main(String[] argv) {
    JMF myFrame = new JMF("Java Media Framework Project");
    myFrame.show();
    myFrame.setSize(300, 300);
  }

}
